package com.example.mychess;

import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import static com.example.mychess.LogonController.*;
import static com.example.mychess.TableController.stg;

public class MainController {
    public static int i=0;
    public  ImageView shi10;
    public  ImageView shi11;
    public  ImageView shi00;
    public  ImageView shi01;
    public  ImageView xiang10;
    public  ImageView xiang11;
    public  ImageView xiang00;
    public  ImageView xiang01;
    public  ImageView ma10;
    public  ImageView ma11;
    public  ImageView ma00;
    public  ImageView ma01;
    public  ImageView che10;
    public  ImageView che11;
    public  ImageView che00;
    public  ImageView che01;
    public  ImageView pao10;
    public  ImageView pao11;
    public  ImageView pao00;
    public  ImageView pao01;
    public  ImageView bing10;
    public  ImageView bing11;
    public  ImageView bing12;
    public  ImageView bing13;
    public  ImageView bing14;
    public  ImageView bing00;
    public  ImageView bing01;
    public  ImageView bing02;
    public  ImageView bing03;
    public  ImageView bing04;
    public  ImageView boss0;
    public ImageView qipan;
    public  ImageView boss1;
    public static List<Chess> cheeses=initCheeses();
    public static Chess firstChess=null;
    public static int thePlayer=0;
    public static int begin=0;
    public static int yuPlayer;
    public static int myTable;
    ClientThread c;

    @FXML
    private void initialize() {
        c=new ClientThread();
        c.start();
    }

    public static class ClientThread extends Thread {

        public ClientThread() {

        }
        @Override
        public void run() {
            while (true) {
                if(i==0){
                    break;
                }
                Object receive= SocketUtil.receive(socket);
                System.out.println(((Message)receive).getType());
                if (receive instanceof Message){
                    Message message = (Message) receive;
                    switch (message.getType()) {
                        case FIGHT -> {
                            System.out.println("有人战斗");
                            fight(message);
                        }
                        case MOVE -> {
                            if(begin!=1){fight(message);}
                            System.out.println("有人移动");
                            move(message);
                        }
                        default -> System.out.println("未知的消息");
                    }
                }
            }
            System.out.println("客户端线程结束");
        }
        private void fight(Message message) {
            if(begin!=1){
                System.out.println("有人加入");
                begin=1;
            }
        }


        private void move(Message msg) {
            if (!Objects.equals(msg.getFrom(), st.getTitle()) &&msg.getTable()==myTable){
                for (Chess chess : cheeses){
                if(getChessByP(msg.getNext())!=null){
                    Chess c = getChessByP(msg.getNext());
                    if (c != null && Objects.equals(chess.getImageView(), c.getImageView())) {
                        System.out.println("tp" + chess.getName() + "来自" + c.getTheP());
                        chess.setTheP(9, 10);
                    }
                }
                }
                for (Chess chess : cheeses){
                    if(Objects.equals(chess.getImageView(),msg.getFirst().getImageView()))
                    {
                        chess.setTheP(msg.getNext());System.out.println(chess.getName()+"移动到"+chess.getTheP());
                    }

                }

                firstChess = null;
                thePlayer =yuPlayer;
            }
        }



    }

    public static List<Chess> initCheeses(){
        // 初始化红方棋子
        List<Chess> c=new ArrayList<>();
        c.add(new Chess("boss0","帅", 0, 4, 0)); // 红帅
        c.add(new Chess("shi00","仕", 0, 3, 0));
        c.add(new Chess("shi01","仕", 0, 5, 0));
        c.add(new Chess("xiang00","相", 0, 2, 0));
        c.add(new Chess("xiang01","相", 0, 6, 0));
        c.add(new Chess("ma00","马", 0, 1, 0));
        c.add(new Chess("ma01","马", 0, 7, 0));
        c.add(new Chess("che00","车", 0, 0, 0));
        c.add(new Chess("che01","车", 0, 8, 0));
        c.add(new Chess("pao00","炮", 0, 1, 2));
        c.add(new Chess("pao01","炮", 0, 7, 2));
        c.add(new Chess("bing00","兵", 0, 0 , 3));
        c.add(new Chess("bing01","兵", 0, 2 , 3));
        c.add(new Chess("bing02","兵", 0, 4 , 3));
        c.add(new Chess("bing03","兵", 0, 6 , 3));
        c.add(new Chess("bing04","兵", 0, 8 , 3));

        // 初始化黑方棋子
        c.add(new Chess("boss1","将", 1, 4, 9)); // 黑将
        c.add(new Chess("shi10","士", 1, 3, 9));
        c.add(new Chess("shi11","士", 1, 5, 9));
        c.add(new Chess("xiang10","象", 1, 2, 9));
        c.add(new Chess("xiang11","象", 1, 6, 9));
        c.add(new Chess("ma10","马", 1, 1, 9));
        c.add(new Chess("ma11","马", 1, 7, 9));
        c.add(new Chess("che10","车", 1, 0, 9));
        c.add(new Chess("che11","车", 1, 8, 9));
        c.add(new Chess("pao10","炮", 1, 1, 7));
        c.add(new Chess("pao11","炮", 1, 7, 7));
        c.add(new Chess("bing10","卒", 1, 0, 6));
        c.add(new Chess("bing11","卒", 1, 2, 6));
        c.add(new Chess("bing12","卒", 1, 4, 6));
        c.add(new Chess("bing13","卒", 1, 6, 6));
        c.add(new Chess("bing14","卒", 1, 8, 6));
        return c;
    }
    public void mouse(MouseEvent mouseEvent) {
        Message msg=new Message();
        paint();
        if(boss0.getLayoutX()==460||boss1.getLayoutX()==460)
        {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("提示");
            if(boss0.getLayoutX()==460) {
                if(yuPlayer==0){
                    myUser.setIntegral(myUser.getIntegral()-2);
                alert.setContentText("你输了");
                    msg.setType(Message.Type.UPDATE_SUCCESS);
                    msg.setFrom(st.getTitle());
                    SocketUtil.send(socket,msg);}
                else {
                    myUser.setIntegral(myUser.getIntegral()+2);
                    alert.setContentText("你赢了");
                    msg.setType(Message.Type.UPDATE_FAILURE);
                    msg.setFrom(st.getTitle());
                    SocketUtil.send(socket,msg);;
                }

            }
            else {
                if(yuPlayer==1){
                    myUser.setIntegral(myUser.getIntegral()-2);
                    alert.setContentText("你输了");
                    msg.setType(Message.Type.UPDATE_FAILURE);
                    msg.setFrom(st.getTitle());
                    SocketUtil.send(socket,msg);}
                else {
                    myUser.setIntegral(myUser.getIntegral()+2);
                    alert.setContentText("你赢了");
                    msg.setType(Message.Type.UPDATE_SUCCESS);
                    msg.setFrom(st.getTitle());
                    SocketUtil.send(socket,msg);;
                }
            }
            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK){
                i=0;
                begin=0;
                stg.close();
                st.show();
            }

            return;
        }

        if (yuPlayer==thePlayer&&begin==1) {
            System.out.println("是你的回合");
            double x = mouseEvent.getX();
            double y = mouseEvent.getY();
            Point p = getPoint((int) x, (int) y);
            System.out.println(p);
            Chess c = getChessByP(p);
            if (c != null) {
                //选子
                if (firstChess == null && c.getPlayer() == thePlayer) {
                    for(Chess ch:cheeses){
                        if(Objects.equals(c.getImageView(),ch.getImageView())){
                            firstChess = ch;
                        }
                    }
                    getImageViewByChess(firstChess).setFitHeight(40);
                    getImageViewByChess(firstChess).setFitWidth(40);
                    System.out.println("firstChess:" + firstChess.getName());
                } else if (firstChess != null) {
                    //换子
                    if (c.getPlayer() == firstChess.getPlayer()) {
                        getImageViewByChess(firstChess).setFitHeight(30);
                        getImageViewByChess(firstChess).setFitWidth(30);
                        for(Chess ch:cheeses){
                            if(Objects.equals(c.getImageView(),ch.getImageView())){
                                firstChess = ch;
                            }
                        }
                        getImageViewByChess(firstChess).setFitHeight(40);
                        getImageViewByChess(firstChess).setFitWidth(40);
                        System.out.println("newChess:" + firstChess.getName());
                    } else {
                        //吃子
                        if (Eat(firstChess, p)) {
                            firstChess.setTheP(p);
                            c.setTheP(9, 10);
                            getImageViewByChess(firstChess).setFitHeight(30);
                            getImageViewByChess(firstChess).setFitWidth(30);
                            msg.setType(Message.Type.MOVE);
                            msg.setFirst(firstChess);
                            msg.setNext(p);
                            msg.setTable(myTable);
                            SocketUtil.send(socket,msg);
                            paint();
                            firstChess = null;
                            thePlayer = change(yuPlayer);
                        }
                    }
                }
            }
            //移动子
            else if (firstChess != null) {
                if (Move(firstChess, p)) {
                    msg.setType(Message.Type.MOVE);
                    msg.setFirst(firstChess);
                    msg.setNext(p);
                    msg.setTable(myTable);
                    msg.setFrom(st.getTitle());
                    SocketUtil.send(socket,msg);
                    firstChess.setTheP(p);
                    getImageViewByChess(firstChess).setFitHeight(30);
                    getImageViewByChess(firstChess).setFitWidth(30);
                    thePlayer = change(yuPlayer);
                    firstChess = null;
                    paint();
                }
            }
        }
        else System.out.println("对方回合");

    }
    public Point getPoint(int x, int y){
        x-=10;y-=10;
        if(x<0||x>450||y<0||y>500) return null;
        return new Point(x/50, y/50);
    }
    public static double getOfX(Point p){
        double x= p.x;
        return x*50+10;
    }
    public  void paint(){
        for (Chess c: cheeses) {
            getImageViewByChess(c).setLayoutX(getOfX(c.getTheP()));
            getImageViewByChess(c).setLayoutY(getOfY(c.getTheP()));
            if(c.getTheP().x==9&&c.getTheP().y==9){
//                getImageViewByChess(c).setVisible(false);
                }
        }
    }
    public static double getOfY(Point p){
        double y= p.y;
        return y*50+10;
    }
    public static Chess getChessByP(Point p){
        for (Chess c: cheeses) {
            if (c.getTheP().x == p.x&&c.getTheP().y==p.y) {
                return c;
            }
        }
        return null;
    }
    public  ImageView getImageViewByChess(Chess c){
        return switch (c.getImageView()) {
            case "shi00" -> shi00;
            case "shi01" -> shi01;
            case "shi10" -> shi10;
            case "shi11" -> shi11;
            case "xiang00" -> xiang00;
            case "xiang01" -> xiang01;
            case "xiang10" -> xiang10;
            case "xiang11" -> xiang11;
            case "ma00" -> ma00;
            case "ma01" -> ma01;
            case "ma10" -> ma10;
            case "ma11" -> ma11;
            case "che00" -> che00;
            case "che01" -> che01;
            case "che10" -> che10;
            case "che11" -> che11;
            case "pao00" -> pao00;
            case "pao01" -> pao01;
            case "pao10" -> pao10;
            case "pao11" -> pao11;
            case "bing00" -> bing00;
            case "bing01" -> bing01;
            case "bing02" -> bing02;
            case "bing03" -> bing03;
            case "bing04" -> bing04;
            case "bing10" -> bing10;
            case "bing11" -> bing11;
            case "bing12" -> bing12;
            case "bing13" -> bing13;
            case "bing14" -> bing14;
            case "boss0" -> boss0;
            case "boss1" -> boss1;
            default -> null;
        };
    }
    public boolean Move(Chess c,Point p){
        return switch (c.getName()) {
            case "帅", "将" -> BossRuler(c, p);
            case "车", "炮" -> CheRuler(c, p);
            case "相", "象" -> XiangRuler(c, p);
            case "士", "仕" -> ShiRuler(c, p);
            case "马" -> MaRuler(c, p);
            case "兵", "卒" -> BingRuler(c, p);
            default -> false;
        };
    }
    public boolean Eat(Chess c,Point p){
        return switch (c.getName()) {
            case "帅", "将" -> BossRuler(c, p);
            case "车" -> CheRuler(c, p);
            case "炮" -> PaoRuler(c, p);
            case "相", "象" -> XiangRuler(c, p);
            case "士", "仕" -> ShiRuler(c, p);
            case "马" -> MaRuler(c, p);
            case "兵", "卒" -> BingRuler(c, p);
            default -> false;
        };
    }
    public boolean BossRuler(Chess c,Point p){
        if(Math.abs(p.x-c.getP().x)>1)
            return false;
        if (Math.abs(p.y-c.getP().y)>2)
            return false;
        if (c.getTheP().x==p.x&&Math.abs(c.getTheP().y-p.y)==1){
            System.out.println("ok");
            return true;
        }
        else if(c.getTheP().y==p.y&&Math.abs(c.getTheP().x-p.x)==1){
            System.out.println("ko");
            return true;
        }
        else {
            System.out.println("TheX:"+c.getTheP().x+" TheY:"+c.getTheP().y);
            System.out.println("x:"+p.x+" y:"+p.y);
            return false;}
    }
    public boolean CheRuler(Chess c,Point p){
        int miny=10;
        int maxy=-1;
        int minx=9;
        int maxx=-1;
        if (c.getTheP().x==p.x){
            for (Chess chess: cheeses){
                if (chess.getTheP() != null) {
                    if ( chess.getTheP().x == p.x && chess.getTheP().y < miny && c.getTheP().y < chess.getTheP().y) {
                        miny = chess.getTheP().y;
                    }
                    if ( chess.getTheP().x == p.x && chess.getTheP().y > maxy && c.getTheP().y > chess.getTheP().y) {
                        maxy = chess.getTheP().y;
                    }
                }
            }
            return p.y >= maxy && p.y <= miny;
        }
        else if(c.getTheP().y==p.y){
            for (Chess chess: cheeses) {
                if (chess.getTheP() != null) {
                    if (chess.getTheP().y == p.y && chess.getTheP().x < minx && c.getTheP().x < chess.getTheP().x) {
                        minx = chess.getTheP().x;
                    }
                    if (chess.getTheP().y == p.y && chess.getTheP().x > maxx && c.getTheP().x > chess.getTheP().x) {
                        maxx = chess.getTheP().x;
                    }
                }
            }
            System.out.println(maxx+" "+minx);
            return p.x >= maxx && p.x <= minx;
        }
        else {
            return false;
        }
    }
    public boolean PaoRuler(Chess c,Point p){
        int miny=10;
        int miny2=10;
        int maxy=-1;
        int maxy2=-1;
        int minx=9;
        int minx2=9;
        int maxx=-1;
        int maxx2=-1;
        if (c.getTheP().x==p.x){
            for (Chess chess: cheeses){
                if (chess.getTheP() != null) {
                    if ( chess.getTheP().x == p.x && chess.getTheP().y < miny && c.getTheP().y < chess.getTheP().y) {
                        miny = chess.getTheP().y;
                    }
                    if ( chess.getTheP().x == p.x && chess.getTheP().y > maxy && c.getTheP().y > chess.getTheP().y) {
                        maxy = chess.getTheP().y;
                    }
                }
            }
            for (Chess chess: cheeses) {
                if (chess.getTheP() != null) {
                    if (chess.getTheP().y!=miny&&chess.getTheP().x == p.x && chess.getTheP().y < miny2 && c.getTheP().y < chess.getTheP().y) {
                        miny2 = chess.getTheP().y;
                    }
                    if (chess.getTheP().y!=maxy&&chess.getTheP().x == p.x && chess.getTheP().y > maxy2 && c.getTheP().y > chess.getTheP().y) {
                        maxy2 = chess.getTheP().y;
                    }
                }
            }
            System.out.println(maxy2+" "+miny2);
            return p.y == maxy2 || p.y == miny2;
        }
        else if(c.getTheP().y==p.y){
            for (Chess chess: cheeses) {
                if (chess.getTheP() != null) {
                    if (chess.getTheP().y == p.y && chess.getTheP().x < minx && c.getTheP().x < chess.getTheP().x) {
                        minx = chess.getTheP().x;
                    }
                    if (chess.getTheP().y == p.y && chess.getTheP().x > maxx && c.getTheP().x > chess.getTheP().x) {
                        maxx = chess.getTheP().x;
                    }
                }
            }
            for (Chess chess: cheeses) {
                if (chess.getTheP() != null) {
                    if (chess.getTheP().x!=minx&&chess.getTheP().y == p.y && chess.getTheP().x < minx2 && c.getTheP().x < chess.getTheP().x) {
                        minx2 = chess.getTheP().x;
                    }
                    if (chess.getTheP().x!=maxx&&chess.getTheP().y == p.y && chess.getTheP().x > maxx2 && c.getTheP().x > chess.getTheP().x) {
                        maxx2 = chess.getTheP().x;
                    }
                }
            }
            System.out.println(maxx2+" "+minx2);
            System.out.println(maxx+" "+minx);
            return p.x == maxx2 || p.x == minx2;
        }
        else {
            return false;
        }
    }
    public boolean XiangRuler(Chess c,Point tp){
        Point p=c.getTheP();
        Point op=c.getP();
        int x= p.x;int y= p.y;
        if(Math.abs(tp.y- op.y)<=4){
            for (Chess tui:cheeses){
                if(tp.x==x+2&&tp.y==y+2&&tui.getTheP().x==x+1&&tui.getTheP().y==y+1)
                    return  false;
                if(tp.x==x-2&&tp.y==y+2&&tui.getTheP().x==x-1&&tui.getTheP().y==y+1)
                    return false;
                if(tp.x==x-2&&tp.y==y-2&&tui.getTheP().x==x-1&&tui.getTheP().y==y-1)
                    return false;
                if(tp.x==x+2&&tp.y==y-2&&tui.getTheP().x==x+1&&tui.getTheP().y==y-1)
                    return  false;
            }
            if(Math.abs(tp.x-x)==2&&Math.abs(tp.y-y)==2)
                return true;
        }
        return false;
    }
    public boolean ShiRuler(Chess c,Point p){
        System.out.println("Chess"+c.getTheP());
        System.out.println("Tp"+p);
        if(p.x>5||p.x<3)
            return false;
        if (c.getP().y==0&&p.y>2)
            return false;
        if(c.getP().y==8&&p.y<6)
            return false;
        return Math.abs(c.getTheP().x - p.x) == 1 && Math.abs(c.getTheP().y - p.y) == 1;
    }
    public boolean MaRuler(Chess c,Point tp){
        Point p=c.getTheP();
        Point op=c.getP();
        int x= p.x;int y= p.y;
            for (Chess tui:cheeses){
               if(tui.getTheP().x==x){
                   if(tui.getTheP().y==y+1){
                       if(Math.abs(tp.x-x)==1&&tp.y==y+2)
                           return false;
                   }
                   else if(tui.getTheP().y==y-1){
                       if(Math.abs(tp.x-x)==1&&tp.y==y-2)
                           return false;
                   }
               }else if(tui.getTheP().y==y){
                   if(tui.getTheP().x==x+1){
                       if(Math.abs(tp.y-y)==1&&tp.x==x+2)
                           return false;
                   }
                   else if(tui.getTheP().x==x-1){
                       if(Math.abs(tp.y-y)==1&&tp.x==x-2)
                           return false;
                   }
               }
            }
        return Math.abs(tp.x - x) == 1 && Math.abs(tp.y - y) == 2 || Math.abs(tp.y - y) == 1 && Math.abs(tp.x - x) == 2;
    }
    public boolean BingRuler(Chess c,Point tp){
        Point p=c.getTheP();
        int x= p.x;int y= p.y;
        if(c.getP().y>4){
            System.out.println("卒");
            if(y>4){
                System.out.println("在家");
                System.out.println((tp.y-y)+" "+(tp.x-x));
                return tp.y - y == -1 && tp.x == x;
            }
            else {
                System.out.println("在外");
                System.out.println((tp.y-y)+" "+(tp.x-x));
                if(tp.y-y==-1&&tp.x==x)
                    return true;
                return Math.abs(tp.x - x) == 1 && tp.y == y;
            }

        }
        else {
            System.out.println("兵");
            if(y<5){
                System.out.println("在家");
                return tp.y-y==1&&tp.x==x;}
            else {
                System.out.println("在外");
                if(tp.y-y==1&&tp.x==x)
                    return true;
                return Math.abs(tp.x - x) == 1 && tp.y == y;
            }
        }
    }
    public static int change(int i){
        if (i==0)return 1;
        else return 0;
    }
}